`
https://leetcode.cn/problems/minimum-window-substring/
`

/**
 * @param {string} s
 * @param {string} t
 * @return {string}
 */
var minWindow = function (s, t) {
  if (t.length > s.length) return ''

  // 存储所有需要的字符
  const needs = {}
  // 窗口中的需要的字符的数量
  const window = {}

  // 初始化所有需要的字符
  for (const c of t) {
    needs[c] = (needs[c] || 0) + 1
  }

  // 当前满足了多少个字符
  let count = 0

  // 左右指针
  let left = 0, right = 0

  // 符合条件字符串的起始位置和长度
  let start = 0, len = Infinity

  // 向右扩展窗口
  while (right < s.length) {
    // 获取新字符
    const c = s[right]
    // 扩展窗口
    right++

    // 如果新字符是需要的字符
    if (needs[c]) {
      // 记录新字符
      window[c] = (window[c] || 0) + 1
      // 字符数量满足要求
      if (window[c] === needs[c]) {
        count++
      }
    }

    // 当收集到所有需要的字符时
    while (count === Object.keys(needs).length) {
      if (len > right - left) {
        len = right - left
        start = left
      }
      const d = s[left]
      left++

      if (needs[d]) {
        if (window[d] === needs[d]) {
          count--
        }
        window[d]--
      }

    }
  }

  return len === Infinity ? '' : s.substring(start, start + len)
};